/**
 * Created by rrzhang on 2019/12/3.
 */
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <unistd.h>

#include <stdio.h>
#include <stdlib.h>
#include <iostream>

#include <event.h>
#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <event2/util.h>

int tcp_connect_server(const char *server_ip, int port);

void cmd_msg_cb(int fd, short events, void *arg);

void server_msg_cb(bufferevent *bev, void *arg);

void event_cb(bufferevent *bev, short event, void *arg);

int main(int argc, char **argv) {
//    if (argc < 3) {
//        printf("please input IP and port\n");
//        return 1;
//    }

    event_base *base = event_base_new();

    bufferevent *bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);

    event *ev_cmd = event_new(base, STDIN_FILENO,
                  EV_READ|EV_PERSIST,
                  cmd_msg_cb, (void *)bev);

    event_add(ev_cmd, NULL);

    ///定义sockaddr_in
    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8989);  //服务器端口
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");  //服务器ip，inet_addr用于IPv4的IP转换（十进制转换为二进制）

    bufferevent_socket_connect(bev, (sockaddr *)&server_addr, sizeof(server_addr));

    bufferevent_setcb(bev, server_msg_cb, NULL, event_cb, (void *)ev_cmd);
    bufferevent_enable(bev, EV_READ|EV_PERSIST);

    event_base_dispatch(base);

    printf("Finished\n");
    return 0;

}

void cmd_msg_cb(int fd, short events, void *arg) {
    char msg[1024];
    int ret = read(fd, msg, sizeof(msg));
    if (ret < 0) {
        perror("read fail.\n");
        exit(1);
    }

    std::string str("hello");
    bufferevent *bev = (bufferevent *)arg;
    bufferevent_write(bev, str.data(), str.length());
}

void server_msg_cb(bufferevent *bev, void *arg) {
    char msg[1024];

    size_t len = bufferevent_read(bev, msg, sizeof(msg)-1);
    msg[len] = '\0';

    printf("Recv %s from server.\n", msg);
}

void event_cb(bufferevent *bev, short event, void *arg) {
    if (event & BEV_EVENT_EOF) {
        printf("Connection closed.\n");
    }
    else if (event & BEV_EVENT_ERROR) {
        printf("Some other error.\n");
    }
    else if (event & BEV_EVENT_CONNECTED) {
        printf("Client has successfully cliented.\n");
        return;
    }

    bufferevent_free(bev);

    // free event_cmd
    // need struct as event is defined as parameter
    struct event *ev = (struct event *)arg;
    event_free(ev);
}